﻿using Flurl.Http;
using NovelDownload.Common;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace NovelDownload
{
    /// <summary>
    /// 文桑小说网
    /// </summary>
    public class WsNovelSite : NovelSiteBase, INovelSiteBase
    {
        public WsNovelSite()
            : base() { }


        public WsNovelSite(string siteName, string siteHomeUrl, string searchSubmitUrl, string baseDownloadUrl)
            : base(siteName, siteHomeUrl, searchSubmitUrl, baseDownloadUrl)
        {
        }


        /// <summary>
        /// 搜索小说
        /// </summary>
        /// <param name="keyword"></param>
        /// <returns></returns>
        public async Task<List<NovelInfo>> SearchNovel(string keyword)
        {
            List<NovelInfo> novels = new List<NovelInfo>();

            string cacheKey = $"{this.SiteName}_search_{keyword}";
            var cacheValue = MemoryCacheHelper.GetCacheItem<List<NovelInfo>>(cacheKey);
            if (cacheValue == null)
            {
                try
                {
                    string htmlCode = await this.SearchSubmitUrl.WithTimeout(10).PostUrlEncodedAsync(new { action = "search", q = keyword }).ReceiveString();
                    var doc = ParseHtml.GetDocument(htmlCode);

                    var dls = doc.QuerySelectorAll("dl");
                    foreach (var dl in dls)
                    {
                        NovelInfo novelInfo = new NovelInfo();
                        var dds = dl.QuerySelectorAll("dd");
                        novelInfo.NovelName = dds[0].QuerySelector("h3 a").InnerHtml;
                        novelInfo.NovelLink = this.SiteHomeUrl + dds[0].QuerySelector("h3 a").Attributes["href"].Value;
                        novelInfo.LatestChapter = dds[3].QuerySelector("a").InnerHtml;
                        novelInfo.Author = dds[1].QuerySelector("span").InnerHtml;
                        novelInfo.UpdateTime = dds[0].QuerySelector("h3 span").InnerHtml;
                        novels.Add(novelInfo);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    return null;
                }

                MemoryCacheHelper.SetCacheItem(cacheKey, novels, TimeSpan.FromMinutes(5));
            }
            else
            {
                novels = cacheValue;
            }

            return novels;
        }


        /// <summary>
        /// 获取全部章节信息
        /// </summary>
        /// <param name="novelUrl"></param>
        /// <returns></returns>
        public async Task<List<ChapterInfo>> GetAllChapterInfo(string novelUrl)
        {
            List<ChapterInfo> chapters = new List<ChapterInfo>();

            string cacheKey = $"{this.SiteName}_{novelUrl}_chapter";
            var cacheValue = MemoryCacheHelper.GetCacheItem<List<ChapterInfo>>(cacheKey);

            if (cacheValue == null)
            {
                string htmlCode = await novelUrl.GetStringAsync();
                var doc = ParseHtml.GetDocument(htmlCode);

                var ulas = doc.QuerySelectorAll("ul.chapter.clear.forwards a");
                foreach (var a in ulas)
                {
                    ChapterInfo chapter = new ChapterInfo();
                    chapter.ChapterTitle = a.FirstElementChild.InnerHtml;
                    chapter.ChapterLink = this.SiteHomeUrl + a.Attributes["href"].Value;
                    chapters.Add(chapter);
                }

                MemoryCacheHelper.SetCacheItem(cacheKey, chapters, TimeSpan.FromMinutes(5));
            }
            else
            {
                chapters = cacheValue;
            }

            return chapters;
        }


        /// <summary>
        /// 获取章节内容
        /// </summary>
        /// <param name="chapterUrl"></param>
        /// <returns></returns>
        public async Task<string> GetChapterContent(string chapterUrl)
        {
            string contentStr;

            string cacheKey = $"{this.SiteName}_chapterContent_{chapterUrl}";
            var cacheValue = MemoryCacheHelper.GetCacheItem<string>(cacheKey);

            if (cacheValue == null)
            {
                string htmlCode = await chapterUrl.GetStringAsync();
                var doc = ParseHtml.GetDocument(htmlCode);

                contentStr = doc.QuerySelector("#BookText").TextContent;

                MemoryCacheHelper.SetCacheItem<string>(cacheKey, contentStr, TimeSpan.FromMinutes(5));
            }
            else
            {
                contentStr = cacheValue;
            }
            return contentStr;
        }


        /// <summary>
        /// 下载小说
        /// </summary>
        /// <param name="downloadUrl"></param>
        public async Task<string> DownloadNovel(string savePath, string downloadUrl, string fileName)
        {
            try
            {
                string path = await downloadUrl.WithTimeout(10).DownloadFileAsync(savePath, fileName);
                return path;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return null;
            }
        }
    }
}
